package io.renren.modules.oss.util;

import java.io.InputStream;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author huan.xu
 * @Date 2022/11/2 17:02
 * @Description ftp 工具类
 */
public class FtpUtils {

    private static Logger logger = LoggerFactory.getLogger(FtpUtils.class);

    /**
     * 获取ftp连接，并登录ftp服务器
     *
     * @return
     */
    public static FTPClient getConnect(String host, int port, String userName, String password) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.setConnectTimeout(1000 * 30);//设置连接超时时间
            ftpClient.setControlEncoding("utf-8");//设置ftp字符集
            ftpClient.enterLocalPassiveMode();//设置被动模式，文件传输端口设置

            // 连接FTP服务器
            ftpClient.connect(host, port);
            // 登录
            ftpClient.login(userName, password);
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                logger.error("登录FTP失败，登录返回码[{}]", replyCode);
                throw new RuntimeException("登录FTP失败");
            }
            //设置上传文件的类型为二进制类型
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        } catch (Exception e) {
            logger.error("连接或者登录ftp错误，错误信息：{}", e);
            throw new RuntimeException("连接或者登录ftp错误");
        }
        logger.info("登录ftp服务器成功");
        return ftpClient;
    }

    /**
     * 向FTP服务器上传文件
     *
     * @param filePath FTP服务器文件存放路径。例如分日期存放：/2015/01/01。文件的路径为basePath+filePath
     * @param fileName 上传到FTP服务器上的文件名
     * @param input    本地要上传的文件的 输入流
     * @return 成功返回true，否则返回false
     */
    public static String uploadFile(String host, int port, String userName, String password,
        String filePath, String fileName, InputStream input)
        throws Exception {
        long startTime = System.currentTimeMillis();
        FTPClient ftpClient = getConnect(host, port, userName, password);

        //切换到上传目录
        if (!ftpClient.changeWorkingDirectory(filePath)) {
            logger.info("开始切换目录");
            //如果目录不存在创建目录
            String[] dirs = filePath.split("/");
            String tempPath = "";
            for (String dir : dirs) {
                if (StringUtils.isBlank(dir)) {
                    continue;
                }
                tempPath += "/" + dir;
                if (!ftpClient.changeWorkingDirectory(tempPath)) {
                    if (!ftpClient.makeDirectory(tempPath)) {
                        logger.error("创建上传目录[{}]失败",tempPath);
                        throw new RuntimeException("创建上传目录失败");
                    } else {
                        ftpClient.changeWorkingDirectory(tempPath);
                    }
                }
            }
        }
        //上传文件
        if (!ftpClient.storeFile(fileName, input)) {
            logger.error("上传文件失败");
            throw new RuntimeException("上传文件失败");
        }
        if (input != null) {
            input.close();
        }
        if (ftpClient != null) {
            ftpClient.logout();
            ftpClient.disconnect();
        }
        long endTime = System.currentTimeMillis();
        logger.info("上传文件到ftp成功，路径为[{}/{}]，花费时间:[{}]ms,[{}]s", filePath, fileName,
            (endTime - startTime), (endTime - startTime) / 1000);
        return filePath;
    }

    public static void main(String[] args) {
        //登录ftp服务器，使用用户名 和密码
//        FtpUtils.login("",21,"ftpUser", "ftpUser");
//        //上传文件
//        FileInputStream inputStream = new FileInputStream(transferToFile);
//
//        ftpHelper.uploadFile(inputStream,path,transferToFile.getName());
    }
}
